package com.slmn.visitor.gui;

import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.layout.HBox;

/**
 * HComposite only allow Leaf and VComposite as Children And Cursor can only add
 * to it.
 * */
public class HComposite extends Composite {

	private final HBox hbox = new HBox();
	private static double initX;
	private static double initY;

	public HComposite() {
		hbox.setPadding(new Insets(0, SPACE, 0, SPACE));
		/**
		 * hbox.setSpacing(SPACE); DON'T uncomment it. HComposite shouldn't have
		 * spacing.
		 **/
		// hbox.setStyle("-fx-border-color: blue;");
		hbox.setAlignment(Pos.CENTER);
		hbox.setOnMouseClicked(mEvent -> {
			if (FormulaFrame.isSelecting) {
				FormulaFrame.isSelecting = false;
				mEvent.consume();
			}
		});
		hbox.setOnMouseDragged(mEvent -> {
			mEvent.consume();
			FormulaFrame.isSelecting = true;
			// Bounds b = hbox.localToScene(hbox.getLayoutBounds());
			Bounds b = hbox.getLayoutBounds();
			double minX = b.getMinX();
			double minY = b.getMinY();
			double maxX = b.getMinX() + b.getWidth();
			double maxY = b.getMinY() + b.getHeight();
			if (mEvent.getX() < initX) {
				FormulaFrame.rect.setX(Math.max(mEvent.getX(), minX));
				FormulaFrame.rect.setWidth(initX
						- Math.max(mEvent.getX(), minX));
			} else {
				FormulaFrame.rect.setX(initX);
				FormulaFrame.rect.setWidth(Math.min(mEvent.getX(), maxX)
						- initX);
			}
			if (mEvent.getY() < initY) {
				FormulaFrame.rect.setY(Math.max(mEvent.getY(), minY));
				FormulaFrame.rect.setHeight(initY
						- Math.max(mEvent.getY(), minY));
			} else {
				FormulaFrame.rect.setY(initY);
				FormulaFrame.rect.setHeight(Math.min(mEvent.getY(), maxY)
						- initY);
			}
		});
		hbox.setOnMousePressed(mEvent -> {
			mEvent.consume();
			initX = mEvent.getX();
			initY = mEvent.getY();
			if (!hbox.getChildren().contains(FormulaFrame.rect)) {
				hbox.getChildren().add(FormulaFrame.rect);
			}
		});
		hbox.setOnMouseReleased(mEvent -> {
			mEvent.consume();
			Cursor.clearCursor();
			FormulaFrame.clearSelected();
			for (Component c : children) {
				HChild hc = (HChild) c;
				if (hc.getCBounds().intersects(
						FormulaFrame.getRectBounds())) {
					FormulaFrame.addSelected(hc);
				}
			}
			FormulaFrame.rect.setX(0);
			FormulaFrame.rect.setY(0);
			FormulaFrame.rect.setWidth(0);
			FormulaFrame.rect.setHeight(0);
			hbox.getChildren().remove(FormulaFrame.rect);
		});
	}

	public void setHboxStyle(String value) {
		hbox.setStyle(value);
	}

	public void addCursor(Component c) {
		if (hbox.getChildren().contains(Cursor.prompt)) {
			hbox.getChildren().remove(Cursor.prompt);
		}
		int index = hbox.getChildren().indexOf(c.getNode());
		if (index == hbox.getChildren().size()) {
			hbox.getChildren().add(Cursor.prompt);
		} else {
			hbox.getChildren().add(index + 1, Cursor.prompt);
		}
	}

	@Override
	protected final boolean isValid(Component c) {
		return c instanceof Leaf || c instanceof VComposite;
	};

	@Override
	public final Parent getNode() {
		return hbox;
	}

	@Override
	protected boolean add(Component c) {
		this.children.add(c);
		return hbox.getChildren().add(c.getNode());
	}

	@Override
	protected boolean remove(Component c) {
		this.children.remove(c);
		return hbox.getChildren().remove(c.getNode());
	}

	public void clear() {
		this.children.clear();
		hbox.getChildren().clear();
	}
}
